# excel2vector.py: 读取 Excel 表结构文件，生成用于向量化的 JSON 文件。
# python ./src/vector/excel2vector.py


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import argparse
import os
import json
from openpyxl import load_workbook

def clean_description(desc):
    """提取左括号 ( 前的内容，并去除首尾空白"""
    if not desc:
        return ""
    # 找到第一个左括号的位置
    paren_index = desc.find('(')
    if paren_index != -1:
        desc = desc[:paren_index]
    return desc.strip()

def main():
    parser = argparse.ArgumentParser(description="将Excel表结构转换为向量化用的JSON文件")
    parser.add_argument(
        '--excel',
        default='./data/表结构.xlsx',
        help='输入的Excel文件路径（默认：./data/表结构.xlsx）'
    )
    parser.add_argument(
        '--output',
        default='vector_output',
        help='输出JSON文件的文件夹路径（默认：vector_output）'
    )
    args = parser.parse_args()

    excel_path = args.excel
    output_dir = args.output

    # 检查输入文件是否存在
    if not os.path.exists(excel_path):
        print(f"错误：Excel文件不存在 -> {excel_path}")
        exit(1)

    # 创建输出目录
    os.makedirs(output_dir, exist_ok=True)

    # 加载工作簿和活动工作表
    try:
        wb = load_workbook(excel_path)
        ws = wb.active
    except Exception as e:
        print(f"无法读取Excel文件：{e}")
        exit(1)

    # 存储当前表的信息
    current_table_name = None
    current_table_desc = None
    current_fields = []  # 用于收集一个表的所有字段行

    # 逐行读取（跳过第一行标题）
    rows_iter = iter(ws.rows)
    next(rows_iter)  # 跳过第一行

    for row in rows_iter:
        values = [cell.value for cell in row]

        # 解包列：序号、表名、表描述、字段名、字段类型、字段描述
        idx = values[0]
        table_name = values[1]
        table_desc = values[2]
        field_name = values[3]
        field_type = values[4]
        field_desc = values[5]

        # 如果表名不为空，说明是新表的开始
        if table_name is not None and str(table_name).strip() != '':
            # 保存前一个表的数据（如果有）
            if current_table_name and current_fields:
                save_table_to_json(current_table_name, current_table_desc, current_fields, output_dir)

            # 开始新表
            current_table_name = str(table_name).strip()
            current_table_desc = str(table_desc).strip() if table_desc else ""
            current_fields = []

        # 继续使用当前表名（即使上面没更新）
        if current_table_name is None:
            continue  # 还没遇到第一个有效表

        # 字段名必须存在
        if field_name is None or str(field_name).strip() == '':
            continue

        field_name = str(field_name).strip()
        field_desc = str(field_desc).strip() if field_desc else ""

        # 只处理以 * 或 ^ 或 $ 开头的字段描述
        if not (field_desc.startswith('*') or field_desc.startswith('^') or field_desc.startswith('$')):
            continue

        # 清洗描述：去掉左括号后的内容
        cleaned_desc = clean_description(field_desc)
        
        # 删除描述开头的 * 或 ^ 或 $ 符号（只删一个）
        if cleaned_desc.startswith('*') or cleaned_desc.startswith('^') or cleaned_desc.startswith('$'):
            cleaned_desc = cleaned_desc[1:].strip()

        # 判断类型：* 或 ^ 是 cond，$ 是 val
        field_type_tag = 'cond' if field_desc.startswith('$') else 'val'
        if field_desc.startswith('$'):
            field_type_tag = 'val'
        else:  # starts with '*' or '^'
            field_type_tag = 'cond'

        # 添加字段信息
        current_fields.append({
            "field": field_name,
            "desc": cleaned_desc,
            "type": field_type_tag
        })

    # 处理最后一个表
    if current_table_name and current_fields:
        save_table_to_json(current_table_name, current_table_desc, current_fields, output_dir)

    print(f"✅ 完成！共处理 {len(os.listdir(output_dir))} 个表，JSON 文件已保存至: {output_dir}")


def save_table_to_json(table_name, table_desc, fields, output_dir):
    """将一个表的数据保存为 JSON 文件"""
    cond_fields = [ {"field": f["field"], "desc": f["desc"]} for f in fields if f["type"] == "cond" ]
    val_fields  = [ {"field": f["field"], "desc": f["desc"]} for f in fields if f["type"] == "val" ]

    data = {
        "table": table_name,
        "name": table_desc,
        "cond": cond_fields,
        "val": val_fields
    }

    filename = f"{table_name}.json"
    filepath = os.path.join(output_dir, filename)

    with open(filepath, 'w', encoding='utf-8') as f:
        json.dump(data, f, ensure_ascii=False, indent=2)

    print(f"生成: {filepath}")


if __name__ == '__main__':
    main()


# python 编写 excel2vector.py 参数 --excel excel文件(默认：./data/表结构.xlsx) --output 输出文件夹(默认：vector_output)
## 读取 excel 输出等待向量化的json文件
### 第一行标题行不读取
###
## excel表头：序号、表名、表描述、字段名、字段类型、字段描述，表名、表描述存在单元格合并情况，字段名、字段类型、字段描述三行不做单元格合并，
### 如：
### 1	area_items_total_day	区县工单统计日表	md_id	int	自增id
###			area_name	string	*地区名称
###			busi_time	string	业务时间
###			total_num	int	$统计总数
## 只提取 * 或 ^ 或 $ 开头字段
## 提取这个字段左括号 ( 前面的字符串
## 字段描述如果 * 或 ^ 开头，表示这是条件字段  cond
## 字段描述如果 $ 开头，表示这是指标字段 val
## 输出json文件名：表名.json ，如 area_items_total_day.json
## json文件内容
### {"table":"表名", "name":"表描述", "cond":[{"field","字段名","desc","字段描述"}...],"val":[{"field","字段名","desc","字段描述"}...]}

# excel2vector.py 写入desc前，检查字段描述如果是* 或 ^ 或 $ 开头，把这个字符删掉，只需要输出改动的程序函数即可